/**
 * Copyright 2008 by Robert Konigsberg
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the same terms as Perl.
 *
 * @see http://www.perl.com/perl/misc/Artistic.html
 */
package visitor.surveyor;

import visitor.edge.Edge;
import visitor.edge.EdgeVisitor;
import visitor.maze.Room;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

public class Surveyor extends EdgeVisitor {

  static class Coordinate {
    public int x;
    public int y;

    public Coordinate(int x, int y) {
      this.x = x;
      this.y = y;
    }

    @Override
    public String toString() {
      return "[ " + x + ", " + y + "]";
    }
  }

  Map<Room, Coordinate> map = new HashMap<Room, Coordinate>();
  private int minX = 0;
  private int minY = 0;
  private int maxX = 0;
  private int maxY = 0;

  Coordinate coordinate = new Coordinate(0, 0);

  public void visit(Edge edge) {
    switch(edge.getHeading()) {
      case EAST: coordinate.x++; break;
      case WEST: coordinate.x--; break;
      case NORTH: coordinate.y++; break;
      case SOUTH: coordinate.y--; break;
    }

    if (!map.containsKey(edge.getTo())) {
      minX = Math.min(minX, coordinate.x);
      maxX = Math.max(maxX, coordinate.x);
      minY = Math.min(minY, coordinate.y);
      maxY = Math.max(maxY, coordinate.y);

      Coordinate c = new Coordinate(coordinate.x, coordinate.y);
      map.put(edge.getTo(), c);
    }
  }

  public void printMap() {
    System.out.println(drawMap());
  }

  private String drawMap() {
    TranslatedArray array = createMapArray();
    return arrayToString(array);
  }

	private TranslatedArray createMapArray() {
		TranslatedArray array = new TranslatedArray(minX, maxX, minY, maxY);
    for (Entry<Room, Coordinate> entry : map.entrySet()) {
      int x = entry.getValue().x;
      int y = entry.getValue().y;
      char c = roomToChar(entry.getKey());
      array.set(x, y, c);
    }
		return array;
	}

	private String arrayToString(TranslatedArray array) {
		StringBuilder sb = new StringBuilder();
    char[][] array2d = array.getArray();
    for (int i = array2d.length - 1; i >= 0; i--) {
    	char[] row = array2d[i];
      for(char c : row) {
        if (c == 0) { c = ' '; }
        sb.append(c);
      }
      sb.append("\n");
    }
    return sb.toString();
	}

  private char roomToChar(Room room) {
    int id = room.getId();
    if (id < 10) {
      return (char) ('0' + id);
    }
    return (char) ('A' + (id - 10));
  }
}
